/********************************************************************
filename : wolf_iic1_common.c
discript : there are more than one devices no I2C1 bus,this file include
					 common function for them.
version  : V0.0
editor   : Icy - dreamwolf
time     : 2014.3.
statement: This file is modified by dreamwolf under LGPL,you could use 
           it free.We cann't ensure there is no error in this file,and
				   if you detect an error please contact us freely,it is so a-
					 ppreciate for your help to improve our code that could help 
					 more people to use it safty.
contact  : edreamtek@163.com
           www.edreamtek.com
********************************************************************/

#include "wolf_iic1_common.h"



void wolf_iic1_init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure; 
	I2C_InitTypeDef I2C_InitStructure;
	

  
  /* Configure the I2C clock source. The clock is derived from the HSI */
  RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
    
  /*!< sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph clock enable */
  RCC_AHBPeriphClockCmd(sEE_I2C_SCL_GPIO_CLK | sEE_I2C_SDA_GPIO_CLK, ENABLE);
  
  /*!< sEE_I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(sEE_I2C_CLK, ENABLE);
  
  /* Connect PXx to I2C_SCL*/
  GPIO_PinAFConfig(sEE_I2C_SCL_GPIO_PORT, sEE_I2C_SCL_SOURCE, sEE_I2C_SCL_AF);
  
  /* Connect PXx to I2C_SDA*/
  GPIO_PinAFConfig(sEE_I2C_SDA_GPIO_PORT, sEE_I2C_SDA_SOURCE, sEE_I2C_SDA_AF);
  
  /*!< GPIO configuration */  
  /*!< Configure sEE_I2C pins: SCL */
  GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  
  /*!< Configure sEE_I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN;
  GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
	
	
	/* I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStructure.I2C_DigitalFilter = 0x00;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_Timing = sEE_I2C_TIMING;
  
  /*!< I2C configuration */
  I2C_Init(sEE_I2C, &I2C_InitStructure);
   
 /* sEE_I2C Peripheral Enable */
  I2C_Cmd(sEE_I2C, ENABLE);
	  	
	I2C_AcknowledgeConfig(sEE_I2C, ENABLE);
	
	I2C_ClearFlag(sEE_I2C,I2C_FLAG_BUSY);
}


void wolf_iic1_write_byte(uint8_t device_addr,uint8_t addr_type,uint16_t dat_addr,uint8_t dat)
{		
	while(I2C_GetFlagStatus(I2C1,I2C_ISR_BUSY) != RESET){};
	
  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, addr_type, I2C_Reload_Mode, I2C_Generate_Start_Write);

	
	if(addr_type == ADDR_16_BITS)
	{
		while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
		I2C_SendData(sEE_I2C,(uint8_t)(0xFF&(dat_addr>>8)));
	}
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
	I2C_SendData(sEE_I2C,(uint8_t)(0xFF&dat_addr));
		
  while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET){};
	
  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);

	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
	I2C_SendData(sEE_I2C,dat);


	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET){};  
  /* Clear STOPF flag */
  I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
}

uint8_t wolf_iic1_read_byte(uint8_t device_addr,uint8_t addr_type,uint16_t dat_addr)
{
	uint8_t dat;
	
	while(I2C_GetFlagStatus(I2C1,I2C_ISR_BUSY) != RESET){};
	
	/* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, addr_type, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);

	
	if(addr_type == ADDR_16_BITS)
	{
		while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
		I2C_SendData(sEE_I2C,(uint8_t)(0xFF&(dat_addr>>8)));
	}
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
	I2C_SendData(sEE_I2C,(uint8_t)(0xFF&dat_addr));

  while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TC) == RESET){};
		
  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
	
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET){};
	
	dat = I2C_ReceiveData(sEE_I2C);

	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET){};  
  /* Clear STOPF flag */
  I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
	
	return dat;
}

void wolf_iic_write_bytes(uint8_t device_addr,uint8_t addr_type,uint16_t dat_addr,uint8_t* pdat,uint16_t cnt)
{
	uint16_t i;
	
	while(I2C_GetFlagStatus(I2C1,I2C_ISR_BUSY) != RESET){};
	
  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, addr_type, I2C_Reload_Mode, I2C_Generate_Start_Write);

	
	if(addr_type == ADDR_16_BITS)
	{
		while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
		I2C_SendData(sEE_I2C,(uint8_t)(0xFF&(dat_addr>>8)));
	}
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
	I2C_SendData(sEE_I2C,(uint8_t)(0xFF&dat_addr));
		
  while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET){};

	/* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, cnt, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
	for(i=0; i<cnt; i++)
	{
    while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET){};
		I2C_SendData(sEE_I2C,*(pdat+i));
	}

	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET){};  
  /* Clear STOPF flag */
  I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
}

void wolf_iic_read_bytes(uint8_t device_addr,uint8_t addr_type,uint16_t dat_addr,uint8_t* pdat,uint16_t NumByteToRead)
{
  uint32_t NumbOfSingle = 0, Count = 0, DataNum = 0, StartCom = 0;
  
  /* Get number of reload cycles */
  Count = (NumByteToRead) / 255;  
  NumbOfSingle = (NumByteToRead) % 255;
	
	while(I2C_GetFlagStatus(I2C1,I2C_ISR_BUSY) != RESET){};
	
	/* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(sEE_I2C, device_addr, addr_type, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);

	
	if(addr_type == ADDR_16_BITS)
	{
		while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
		I2C_SendData(sEE_I2C,(uint8_t)(0xFF&(dat_addr>>8)));
	}
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXE) == RESET){};
	I2C_SendData(sEE_I2C,(uint8_t)(0xFF&dat_addr));

  while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TC) == RESET){};
		
		
	/* If number of Reload cycles is not equal to 0 */
  if (Count != 0)
  {
    /* Starting communication */
    StartCom = 1;
    
    /* Wait until all reload cycles are performed */
    while( Count != 0)
    { 
      /* If a read transfer is performed */
      if (StartCom == 0)      
      {
        /* Wait until TCR flag is set */
        while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET){};
      }      
      
      /* if remains one read cycle */
      if ((Count == 1) && (NumbOfSingle == 0))
      {
        /* if starting communication */
        if (StartCom != 0)
        {
          /* Configure slave address, end mode and start condition */
          I2C_TransferHandling(sEE_I2C, device_addr, 255, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
        }
        else
        {
          /* Configure slave address, end mode */
          I2C_TransferHandling(sEE_I2C, device_addr, 255, I2C_AutoEnd_Mode, I2C_No_StartStop);          
        }
      }
      else 
      {
        /* if starting communication */
        if (StartCom != 0)
        {
          /* Configure slave address, end mode and start condition */
          I2C_TransferHandling(sEE_I2C, device_addr, 255, I2C_Reload_Mode, I2C_Generate_Start_Read);
        }
        else
        {
          /* Configure slave address, end mode */
          I2C_TransferHandling(sEE_I2C, device_addr, 255, I2C_Reload_Mode, I2C_No_StartStop);          
        } 
      }
      
      /* Update local variable */
      StartCom = 0;      
      DataNum = 0;
      
      /* Wait until all data are received */
      while (DataNum != 255)
      {        
        /* Wait until RXNE flag is set */
        while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET){};
        
        /* Read data from RXDR */
        pdat[DataNum]= I2C_ReceiveData(sEE_I2C);
        
        /* Update number of received data */
        DataNum++;
        (NumByteToRead)--;
      }      
      /* Update Pointer of received buffer */ 
      pdat += DataNum;  
      
      /* update number of reload cycle */
      Count--;
    }
    
    /* If number of single data is not equal to 0 */
    if (NumbOfSingle != 0)
    {            
      /* Wait until TCR flag is set */
      while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET){};
      
      /* Update CR2 : set Nbytes and end mode */
      I2C_TransferHandling(sEE_I2C, device_addr, (uint8_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_No_StartStop);
      
      /* Reset local variable */
      DataNum = 0;
      
      /* Wait until all data are received */
      while (DataNum != NumbOfSingle)
      {        
        /* Wait until RXNE flag is set */
        while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET){};
        
        /* Read data from RXDR */
        pdat[DataNum]= I2C_ReceiveData(sEE_I2C);
        
        /* Update number of received data */
        DataNum++;
        (NumByteToRead)--;
      } 
    }
  }
  else
  {
    /* Update CR2 : set Slave Address , set read request, generate Start and set end mode */
    I2C_TransferHandling(sEE_I2C, device_addr, (uint32_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
    
    /* Reset local variable */
    DataNum = 0;
    
    /* Wait until all data are received */
    while (DataNum != NumbOfSingle)
    {
      /* Wait until RXNE flag is set */
      while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET){};
      
      /* Read data from RXDR */
      pdat[DataNum]= I2C_ReceiveData(sEE_I2C);
      
      /* Update number of received data */
      DataNum++;
      (NumByteToRead)--;
    }
	}    


	/* Configure slave address, nbytes, reload, end mode and start or stop generation 
  I2C_TransferHandling(sEE_I2C, device_addr, cnt, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
	
	
	for(i=0; i<cnt-1; i++)
	{
		while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET){};
		*(pdat+i) =I2C_ReceiveData(I2C1);
		delay_10ms(1);
	}
*/
	while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET){};  
  /* Clear STOPF flag */
  I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
}


